/**
 * @version 1.0
 * @author Ha Giang
 * @date
 */
package DiscoveryFunction;

import Communications.Multicast;
import Configuration.Utils;
import java.util.Enumeration;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This thread processes messages from services
 *
 */
public class ServicesProcessorThread extends Thread {

    private ConcurrentHashMap<String, ServiceInfo> services = null;
    private Multicast mc;
    Queue announcement;

    /**
     * Constructor
     *
     * @param _dir The Directory who creates this thread
     */
    public ServicesProcessorThread(Directory _dir) {
        mc = new Multicast();
        announcement = mc.startMulticastServiceChannel();
        services = _dir.getServices();
    }

    /**
     * Process a register message. Add/update services
     * @param reg The string contains Register message
     */
    public void processReg(String reg) {
        //reg follows the format "REG XXXXXXXXXXXXXXXXXXX", where XXXXXX is the servier info
        //msg contains the XXXXXX part
        String msg = reg.split(" ")[1];
        //extract info from msg, 
        ServiceInfo si = new ServiceInfo();
        si.loadString(msg);
        //add/update to hash table
        services.put(si.getUuid(), si);
        System.out.println("Directory:" + si.getUuid() + "...IP:" + si.getIp() + " updated/added");
        //announce to service channel
        mc.announceMsgToServiceChannel("Directory:" + si.getUuid() + "...IP:" + si.getIp() + " updated/added");
    }

    /**
     * List all available services 
     */
    public void listAllServices() {
        System.out.println("Directory: Listing services! # of services: " + services.size());
        Enumeration e = services.keys();

        //iterate through Hashtable keys Enumeration
        while (e.hasMoreElements()) {
            Object o = e.nextElement();
            System.out.println(o + "-->" + services.get(o));
        }
    }

    @Override
    public void run() {
        String s;
        while (true) {
            while (!announcement.isEmpty()) {
                //take one string fromt the announcement
                s = (String) announcement.remove();
                if (s != null) {
                    System.out.println("Directoty: Get msg from Service channel:" + s);

                    if (s.startsWith("REG")) {
                        processReg(s);
                        //list all services (for debug)
                        if (Utils.MODE == Utils.DEBUG_MODE) {
                            listAllServices();
                        }
                    }
                }
            }
        }
    }
}
